#include "include.h"
#include "gui/gridhelper.h"
#include "gui/graphicview.h"

#include "compile/debug_memoryleaks"

using namespace gui;

GridHelper::GridHelper(GraphicView& graphicview)
: Helper(graphicview)
{
	//ctor
	clear();
}

GridHelper::~GridHelper()
{
	//dtor
	clear();
}


void GridHelper::rebuild(int minGridSpacing /*=10*/, Vector userGrid /*= Vector(-1.0, -1.0)*/ , bool scaleGrid /*= true*/)
{
	clear();

	Vector gridWidth;
	Vector metaGridWidth;

	// init grid spacing:
	// metric grid:
	//    if (RS_Units::isMetric(unit) || unit==RS2::None || format==RS2::Decimal || format==RS2::Engineering)
	{
		if (userGrid.x>0.0)
		{
			gridWidth.x = userGrid.x;
		}
		else
		{
			gridWidth.x = 0.000001;
		}

		if (userGrid.y>0.0)
		{
			gridWidth.y = userGrid.y;
		}
		else
		{
			gridWidth.y = 0.000001;
		}

		// auto scale grid
		if (scaleGrid)
		{
			while (graphicview.toGuiDX(gridWidth.x)<minGridSpacing)
			{
				gridWidth.x*=10;
			}
			while (graphicview.toGuiDY(gridWidth.y)<minGridSpacing)
			{
				gridWidth.y*=10;
			}
		}
		metaGridWidth.x = gridWidth.x*10;
		metaGridWidth.y = gridWidth.y*10;

	}

//            // imperial grid:
//            else {
//
//                RS_DEBUG->print("RS_Grid::update: 005");
//
//                if (userGrid.x>0.0) {
//                    gridWidth.x = userGrid.x;
//                }
//                else {
//                    gridWidth.x = 1.0/1024.0;
//                }
//
//                if (userGrid.y>0.0) {
//                    gridWidth.y = userGrid.y;
//                }
//                else {
//                    gridWidth.y = 1.0/1024.0;
//                }
//                RS_DEBUG->print("RS_Grid::update: 006");
//
//                if (unit==RS2::Inch) {
//                    RS_DEBUG->print("RS_Grid::update: 007");
//
//                    // auto scale grid
//                    if (scaleGrid) {
//                        while (graphicview.toGuiDX(gridWidth.x)<minGridSpacing) {
//                            if (RS_Math::round(gridWidth.x)>=36) {
//                                gridWidth.x*=2;
//                            } else if (RS_Math::round(gridWidth.x)>=12) {
//                                gridWidth.x*=3;
//                            } else if (RS_Math::round(gridWidth.x)>=4) {
//                                gridWidth.x*=3;
//                            } else if (RS_Math::round(gridWidth.x)>=1) {
//                                gridWidth.x*=2;
//                            } else {
//                                gridWidth.x*=2;
//                            }
//                        }
//                        while (graphicview.toGuiDY(gridWidth.y)<minGridSpacing) {
//                            if (RS_Math::round(gridWidth.y)>=36) {
//                                gridWidth.y*=2;
//                            } else if (RS_Math::round(gridWidth.y)>=12) {
//                                gridWidth.y*=3;
//                            } else if (RS_Math::round(gridWidth.y)>=4) {
//                                gridWidth.y*=3;
//                            } else if (RS_Math::round(gridWidth.y)>=1) {
//                                gridWidth.y*=2;
//                            } else {
//                                gridWidth.y*=2;
//                            }
//                        }
//                    }
//
//                    RS_DEBUG->print("RS_Grid::update: 008");
//
//                    // metagrid X shows inches..
//                    metaGridWidth.x = 1.0;
//
//                    if (graphicview.toGuiDX(metaGridWidth.x)<minGridSpacing*2) {
//                        // .. or feet
//                        metaGridWidth.x = 12.0;
//
//                        // .. or yards
//                        if (graphicview.toGuiDX(metaGridWidth.x)<minGridSpacing*2) {
//                            metaGridWidth.x = 36.0;
//
//                            // .. or miles (not really..)
//                            //if (graphicview.toGuiDX(metaGridWidth.x)<20) {
//                            //    metaGridWidth.x = 63360.0;
//                            //}
//
//                            // .. or nothing
//                            if (graphicview.toGuiDX(metaGridWidth.x)<minGridSpacing*2) {
//                                metaGridWidth.x = -1.0;
//                            }
//
//                        }
//                    }
//
//                    RS_DEBUG->print("RS_Grid::update: 009");
//
//                    // metagrid Y shows inches..
//                    metaGridWidth.y = 1.0;
//
//                    if (graphicview.toGuiDY(metaGridWidth.y)<minGridSpacing*2) {
//                        // .. or feet
//                        metaGridWidth.y = 12.0;
//
//                        // .. or yards
//                        if (graphicview.toGuiDY(metaGridWidth.y)<minGridSpacing*2) {
//                            metaGridWidth.y = 36.0;
//
//                            // .. or miles (not really..)
//                            //if (graphicview.toGuiDY(metaGridWidth.y)<20) {
//                            //    metaGridWidth.y = 63360.0;
//                            //}
//
//                            // .. or nothing
//                            if (graphicview.toGuiDY(metaGridWidth.y)<minGridSpacing*2) {
//                                metaGridWidth.y = -1.0;
//                            }
//
//                        }
//                    }
//
//                    RS_DEBUG->print("RS_Grid::update: 010");
//                } else {
//
//                    RS_DEBUG->print("RS_Grid::update: 011");
//
//                    if (scaleGrid) {
//                        while (graphicview.toGuiDX(gridWidth.x)<minGridSpacing) {
//                            gridWidth.x*=2;
//                        }
//                        metaGridWidth.x = -1.0;
//
//                        while (graphicview.toGuiDY(gridWidth.y)<minGridSpacing) {
//                            gridWidth.y*=2;
//                        }
//                        metaGridWidth.y = -1.0;
//                    }
//                    RS_DEBUG->print("RS_Grid::update: 012");
//                }
//                //gridWidth.y = gridWidth.x;
//                //metaGridWidth.y = metaGridWidth.x;
//            }
//


	// for grid info:
	spacing = gridWidth.x;
	metaSpacing = metaGridWidth.x;

	if (gridWidth.x>1.0e-6 && gridWidth.y>1.0e-6 &&
		graphicview.toGuiDX(gridWidth.x)>2 &&
		graphicview.toGuiDY(gridWidth.y)>2) {

			// find grid boundaries
			double left = (int)(graphicview.toGraphX(0) / gridWidth.x)
				* gridWidth.x;
			double right = (int)(graphicview.toGraphX(graphicview.getWidth()) /
				gridWidth.x) * gridWidth.x;
			double top = (int)(graphicview.toGraphY(0) /
				gridWidth.y) * gridWidth.y;
			double bottom =
				(int)(graphicview.toGraphY(graphicview.getHeight()) /
				gridWidth.y) * gridWidth.y;


			left -= gridWidth.x;
			right += gridWidth.x;
			top += gridWidth.y;
			bottom -= gridWidth.y;


			// calculate number of visible grid points
			int numberX = (Math::round((right-left) / gridWidth.x) + 1);
			int numberY = (Math::round((top-bottom) / gridWidth.y) + 1);
			int number = numberX*numberY;



			// create grid array:
			if (number>0 && number<1000000)
			{
				for (int y=0; y<numberY; ++y)
				{
					for (int x=0; x<numberX; ++x)
					{
						pt.push_back( Vector(left+x*gridWidth.x, bottom+y*gridWidth.y) );
					}
				}
			}

	}


	// find meta grid boundaries
	if (metaGridWidth.x>1.0e-6 && metaGridWidth.y>1.0e-6 &&
		graphicview.toGuiDX(metaGridWidth.x)>2 &&
		graphicview.toGuiDY(metaGridWidth.y)>2)
	{

		double mleft = (int)(graphicview.toGraphX(0) /
			metaGridWidth.x) * metaGridWidth.x;
		double mright = (int)(graphicview.toGraphX(graphicview.getWidth()) /
			metaGridWidth.x) * metaGridWidth.x;
		double mtop = (int)(graphicview.toGraphY(0) /
			metaGridWidth.y) * metaGridWidth.y;
		double mbottom = (int)(graphicview.toGraphY(graphicview.getHeight()) /
			metaGridWidth.y) * metaGridWidth.y;

		mleft -= metaGridWidth.x;
		mright += metaGridWidth.x;
		mtop += metaGridWidth.y;
		mbottom -= metaGridWidth.y;

		// calculate number of visible meta grid lines:
		int numMetaX = (Math::round((mright-mleft) / metaGridWidth.x) + 1);
		int numMetaY = (Math::round((mtop-mbottom) / metaGridWidth.y) + 1);

		if (numMetaX>0 && numMetaY>0)
		{
			// create meta grid arrays:

			for (int x=0; x<numMetaX; ++x)
			{
				metaX.push_back( mleft+x*metaGridWidth.x );
			}

			for (int y=0; y<numMetaY; ++y)
			{
				metaY.push_back( mbottom+y*metaGridWidth.y );
			}
		}
	}
}


void GridHelper::clear()
{
	pt.clear();
	metaX.clear();
	metaY.clear();
	spacing = metaSpacing = 0;
}
